#pragma once
#include <list>
#include "vector.h"

/**
 * Klasa sfery otaczajacej
 *
 * @author Krzysztof Klein
 * @version 0.1
 */
class BoundingSphere
{

	/**
	 * Srodek sfery
	 */
	Vector center;

	/**
	 * Promien sfery
	 */
	float radius;

public:

	/**
	 * Konstruktor domyslny
	 */
	BoundingSphere() : center(0.0f, 0.0f, 0.0f), radius(0.0f) { }

	/**
	 * Konstruktor z srodkiem i promieniem
	 *
	 * @param center Srodek sfery
	 * @param radius Promien sfery
	 */
	BoundingSphere(const Vector &center, float radius) : center(center), radius(radius) { }

	/**
	 * Konstruktor z lista punktow
	 *
	 * @param points Lista punktow
	 */
	BoundingSphere(const std::list<Vector> &points)
		: center(0.0f, 0.0f, 0.0f), radius(0.0f)
	{
		std::list<Vector>::const_iterator it;
		float radiusSquared = 0.0f;

		if(points.size() == 0)
			return;

		// oblicz srodek
		for(it = points.begin(); it != points.end(); it++)
			center += (*it);
		center /= (float)points.size();

		// oblicz promien
		float d;
		for(it = points.begin(); it != points.end(); it++)
			if((d = ((*it)-center).getLengthSquared()) > radiusSquared)
				radiusSquared = d;
		radius = sqrt(radiusSquared);
	}


	/**
	 * Srodek sfery
	 *
	 * @return Srodek sfery
	 */
	Vector& getCenter() { return center; }

	/**
	 * Srodek sfery
	 *
	 * @return Srodek sfery
	 */
	const Vector& getCenter() const { return center; }

	/**
	 * Promien sfery
	 *
	 * @return Promien sfery
	 */
	float getRadius() const { return radius; }


	/**
	 * Sprawdza czy jest kolizja ze sfera
	 *
	 * @param sphereCenter Srodek sfery
	 * @param sphereRadius Promien sfery
	 * @return True jesli jest kolizja. False jesli nie.
	 */
	bool isCollidingWithSphere(const Vector &sphereCenter, float sphereRadius = 1.0f) const
	{
		return (sphereCenter - center).getLengthSquared() <=
			((radius + sphereRadius) * (radius + sphereRadius));
	}

};
